package site.shenjie.my.loadbalanced.interceptor;

import lombok.Data;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestFactory;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.Assert;

import java.io.IOException;
import java.net.URI;

/**
 * 沈杰
 * 2020-7-24 11:45:56
 * 拦截器：演示@LoadBalanced内部运行机制
 */
@Data
public class MyLoadBalancerInterceptor implements ClientHttpRequestInterceptor {
    private LoadBalancerClient loadBalancer;
    private LoadBalancerRequestFactory requestFactory;

    /**
     * 构造函数：为成员变量赋值
     */
    public MyLoadBalancerInterceptor() {

    }

    /**
     * 构造函数：为成员变量赋值
     */
    public MyLoadBalancerInterceptor(LoadBalancerClient loadBalancer, LoadBalancerRequestFactory requestFactory) {
        this.loadBalancer = loadBalancer;
        this.requestFactory = requestFactory;
    }

    /**
     * 构造函数：为成员变量赋值
     */
    public MyLoadBalancerInterceptor(LoadBalancerClient loadBalancer) {
        this(loadBalancer, new LoadBalancerRequestFactory(loadBalancer));
    }

    /**
     * 接口约定的必须实现的方法：
     * 一个简单的拦截器，看看在调用接口之前会不会进入这个拦截器。我们不做任何操作，就输出一句话，证明能进来就行了。
     */
    @Override
    public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
        // 拿到请求的URI
        final URI originalUri = httpRequest.getURI();
        // 拿到请求的主机名
        String serviceName = originalUri.getHost();
        System.out.println("进入自定义的请求拦截器中" + serviceName);

        Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);
        // 这里只是机制演示而已，所以这里报空指针异常是正常的，因为没有专门地编写整体配合代码
        return this.loadBalancer.execute(serviceName, requestFactory.createRequest(httpRequest, bytes, clientHttpRequestExecution));
    }
}
